package com.framework.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;


@Component
@Aspect
public class LogAspects {

    @Pointcut("execution(* com.framework.service.impl.*.*(..))")
    public void serviceLayer() {
    }

    // 切入点
    @Before("serviceLayer()")
    public void start(JoinPoint joinPoint) {
        // 目标对象名称，（全路径名称）
        String className = joinPoint.getTarget().getClass().getName();
        // 切入点方法名称
        String methodName = joinPoint.getSignature().getName();
        // 方法信息
        Object[] args = joinPoint.getArgs();
        System.out.println("[before] 前置方法：目标类对象：" + className
                + "，切入点方法名称：" + methodName + "，参数信息：" + Arrays.toString(args));
    }

    /**
     * 后置返回
     *
     * @param joinPoint   用于获取目标对象、方法名等
     * @param returnValue 用于获取返回值
     */
    @AfterReturning(value = "serviceLayer()", returning = "returnValue")
    public void returnValue(JoinPoint joinPoint, Object returnValue) {
        // 目标对象
        String classPath = joinPoint.getTarget().getClass().getName();
        // 目标方法
        String methodName = joinPoint.getSignature().getName();
        // 方法参数
        Object[] args = joinPoint.getArgs();
        // 返回结果
        System.out.println("[AfterReturning] 后置返回：目标类对象：" + classPath + "，切入点方法名称：" + methodName
                + "，参数信息：" + Arrays.toString(args)
                + "，返回结果：" + returnValue);
    }

    @After("serviceLayer()")
    public void end(JoinPoint joinPoint){
        // 目标类对象
        String classPath = joinPoint.getTarget().getClass().getName();
        // 切入点方法名称
        String methodName = joinPoint.getSignature().getName();
        // 参数信息
        Object[] args = joinPoint.getArgs();

        System.out.println("[After] 后置方法：目标类对象：" + classPath
                + "，切入点方法名称：" + methodName + "，参数信息：" + Arrays.toString(args));

    }

    @AfterThrowing(value = "serviceLayer()",throwing = "throwable")
    public void exception(JoinPoint joinPoint, Throwable throwable) {
        // 目标对象
        String classPath = joinPoint.getTarget().getClass().getName();
        // 切面方法
        String methodName = joinPoint.getSignature().getName();
        // 参数信息
        Object[] args = joinPoint.getArgs();

        String message = throwable.getMessage();

        System.out.println("[AfterThrowing] 后置异常：目标类对象：" + classPath
                + "，切入点方法名称：" + methodName + "，参数信息：" + Arrays.toString(args)
                + ", 异常信息：" + message
        );
    }

}
